feat: add first-party Tinybird analytics#2003
Conversation
|
hey @greptileai, please re-review the PR |
|
hey @greptileai, please re-review the PR |
|
hey @greptileai, please re-review the PR |
|
hey @greptileai, please re-review the PR |
|
hey @greptileai, please re-review the PR |
|
hey @greptileai, please re-review the PR |
|
hey @greptileai, please re-review the PR |
|
hey @greptileai, please re-review the PR |
| const browserClaims = | ||
| hasExpectedBrowserAnalyticsMetadata( | ||
| requestMetadata, | ||
| allowedOrigins, | ||
| ) && | ||
| readProductAnalyticsBrowserTokenClaims( | ||
| readProductAnalyticsBrowserToken(headers.cookie), | ||
| serverEnv().NEXTAUTH_SECRET, | ||
| ); |
There was a problem hiding this comment.
Minor robustness nit: if token claim parsing throws (bad secret, malformed cookie, etc) this will currently 500. I'd rather treat that as “no browser claims” and let it fall through to the normal BadRequest path.
| const browserClaims = | |
| hasExpectedBrowserAnalyticsMetadata( | |
| requestMetadata, | |
| allowedOrigins, | |
| ) && | |
| readProductAnalyticsBrowserTokenClaims( | |
| readProductAnalyticsBrowserToken(headers.cookie), | |
| serverEnv().NEXTAUTH_SECRET, | |
| ); | |
| let browserClaims; | |
| if ( | |
| hasExpectedBrowserAnalyticsMetadata( | |
| requestMetadata, | |
| allowedOrigins, | |
| ) | |
| ) { | |
| try { | |
| browserClaims = readProductAnalyticsBrowserTokenClaims( | |
| readProductAnalyticsBrowserToken(headers.cookie), | |
| serverEnv().NEXTAUTH_SECRET, | |
| ); | |
| } catch { | |
| browserClaims = undefined; | |
| } | |
| } |
| if (result.error || result.status !== 0) { | ||
| throw new Error("Unable to verify Tinybird workspace identity."); | ||
| } |
There was a problem hiding this comment.
This failure path drops the actual stderr/stdout, which makes CI deploy debugging pretty painful. I’d include stderr (trimmed) in the thrown error message.
| if (result.error || result.status !== 0) { | |
| throw new Error("Unable to verify Tinybird workspace identity."); | |
| } | |
| if (result.error || result.status !== 0) { | |
| const stderr = (result.stderr ?? "").toString().trim(); | |
| throw new Error( | |
| stderr | |
| ? `Unable to verify Tinybird workspace identity: ${stderr}` | |
| : "Unable to verify Tinybird workspace identity.", | |
| ); | |
| } |
a9b199c to
fee7c3a
Compare
| { | ||
| eventId, | ||
| eventName: event.eventName, | ||
| occurredAt: event.occurredAt ?? new Date().toISOString(), |
There was a problem hiding this comment.
Small robustness thing: occurredAt is passed through as-is, so a bad caller value will land as a bad timestamp in Tinybird. Might be worth normalizing/validating and falling back to now.
| occurredAt: event.occurredAt ?? new Date().toISOString(), | |
| occurredAt: | |
| event.occurredAt && Number.isFinite(Date.parse(event.occurredAt)) | |
| ? new Date(event.occurredAt).toISOString() | |
| : new Date().toISOString(), |
| const client = new PostHog(key, { host }); | ||
| client.capture({ | ||
| distinctId: event.distinctId, | ||
| event: event.eventName, | ||
| properties: event.properties, | ||
| }); | ||
| await client.shutdown(); |
There was a problem hiding this comment.
Minor cleanup: if client.capture throws, shutdown() won’t run. I’d wrap shutdown in a finally.
| const client = new PostHog(key, { host }); | |
| client.capture({ | |
| distinctId: event.distinctId, | |
| event: event.eventName, | |
| properties: event.properties, | |
| }); | |
| await client.shutdown(); | |
| const client = new PostHog(key, { host }); | |
| try { | |
| client.capture({ | |
| distinctId: event.distinctId, | |
| event: event.eventName, | |
| properties: event.properties, | |
| }); | |
| } finally { | |
| await client.shutdown(); | |
| } |
Summary
Validation
pnpm analytics:test— 146 tests passedpnpm typecheckcargo fmt --all -- --checkcargo check -p cap-desktopcargo test -p cap-desktop posthog --lib— 11 tests passedRollout gate
Explicit PostHog dual-write remains until 14 days of parity and a durable purchase outbox/replay path exist. Tinybird Local runtime build and fixture execution are delegated to this PR's analytics workflow.
Greptile Summary
This PR adds first-party Tinybird product analytics across web, desktop, and deployment tooling. The main changes are:
/api/eventsingestion path for bounded client analytics.Confidence Score: 5/5
This looks safe to merge.
Important Files Changed
Reviews (9): Last reviewed commit: "fix: parse Tinybird workspace identity" | Re-trigger Greptile
Context used: